Introduction to Bokeh

Bokeh is an open-source Python interactive visualization library from Continuum Analytics that targets modern web browsers for presentation.

Bokeh includes an example of network visualization as a matrix using character co-appearance data from Les Misérables.

Sandbook provides some convenience functions to render the matrix using data from an igraph instance.

Convert the sample data into an igraph-compatible format


In [1]:
from bokeh.sampledata.les_mis import data

In [2]:
data.keys()


Out[2]:
dict_keys(['nodes', 'links'])

In [3]:
len(data['nodes'])


Out[3]:
77

In [4]:
data['nodes'][0:5]


Out[4]:
[{'name': 'Myriel', 'group': 1},
 {'name': 'Napoleon', 'group': 1},
 {'name': 'Mlle.Baptistine', 'group': 1},
 {'name': 'Mme.Magloire', 'group': 1},
 {'name': 'CountessdeLo', 'group': 1}]

We'll need to add an id to the vertices:


In [5]:
vertices = [dict(d, id=i) for d, i in zip(data['nodes'], range(len(data['nodes'])))]

In [6]:
data['links'][0:5]


Out[6]:
[{'source': 1, 'target': 0, 'value': 1},
 {'source': 2, 'target': 0, 'value': 8},
 {'source': 3, 'target': 0, 'value': 10},
 {'source': 3, 'target': 2, 'value': 6},
 {'source': 4, 'target': 0, 'value': 1}]

Edges should have a weight attribute:


In [7]:
edges = [dict(d, weight=d['value']) for d in data['links']]

We now have everything we need to load the graph. Note that chapter co-appearance is a reciprocal relationship, and so the network should be loaded as directed=False so that indegree and outdegree metrics are computed correctly:


In [8]:
import sand

In [9]:
g = sand.from_vertices_and_edges(
                vertices=vertices, 
                edges=edges, 
                vertex_name_key='name', 
                vertex_id_key='id', 
                edge_foreign_keys=('source', 'target'),
                directed=False)
g.summary()


Out[9]:
'IGRAPH UNW- 77 254 -- \n+ attr: group (v), id (v), indegree (v), label (v), name (v), outdegree (v), source (e), target (e), value (e), weight (e)'

Create a color palette

We want to choose a color palette so that groups stand out.

Find the number of groups that you have assigned to your vertices:


In [10]:
num_groups = max(list(map(lambda x: x['group'], data['nodes'])))
num_groups


Out[10]:
10

Now we need to choose an appropriate palette that accomodates this number of groups and achieves the desired visual separation.

As a general rule, you'll need one of the large palettes for > 20 groups.

Pass the name of the palette you choose to the all_palettes function:


In [11]:
from bokeh.plotting import show, output_notebook
from bokeh.palettes import all_palettes

output_notebook()


Loading BokehJS ...

In [12]:
palette = all_palettes['Paired'][num_groups + 1]

A palette is simply a list of hex colors:


In [13]:
palette


Out[13]:
['#a6cee3',
 '#1f78b4',
 '#b2df8a',
 '#33a02c',
 '#fb9a99',
 '#e31a1c',
 '#fdbf6f',
 '#ff7f00',
 '#cab2d6',
 '#6a3d9a',
 '#ffff99']

You can always resort to defining your own custom list, as was done in the original bokeh example:


In [14]:
palette = ["#444444", "#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99",
           "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a"]

Determine the order to sort the vertex labels

The matrix visualization will be rendered according to a vertex attribute used as the sort_by parameter in matrix.


In [15]:
g.vs.attributes()


Out[15]:
['name', 'group', 'id', 'indegree', 'outdegree', 'label']

Render the matrix


In [16]:
p = sand.matrix(g, 'group', "Les Mis Occurrences", 900, palette)
show(p)


We could also sort by one of the computed vertex attributes like indegree:


In [17]:
p = sand.matrix(g, 'indegree', "Les Mis Occurrences", 900, palette)
show(p)


With the matrix visualization in hand, we can now create a Dependency Structure Matrix (or DSM) with the lein topology dataset. Coming Soon